package 基础;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;
    TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        while(true){
            //从缓冲区内取出并同意链接
            //将取出的数据使用clientSocket另外保存起来，
            //每有一个客户端，就会出现一个clientSocket对象，所有使用完，必须关闭
            Socket clientSocket = serverSocket.accept();
            //进行数据分析

/*            Thread t = new Thread(()->{
                processConnection(clientSocket);
            });
            t.start();*/
//            这样写开销大，会有很多次的创建和销毁，改进使用线程池

            ExecutorService service = Executors.newFixedThreadPool(3);
            service.submit(()->{
                processConnection(clientSocket);
            });
        }
    }

    //使用这个方法专门处理一次连接，在一次连接中可能会涉及多次请求交互
    private void processConnection(Socket clientSocket) {
        System.out.printf("[客户端ip：%s,端口号：%d],客户端上线\n",clientSocket.getInetAddress(),clientSocket.getPort());
        //循环处理请求并返回响应（请求可能不止一次）
        //从网卡中读数据和写数据
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()){
            while (true){
//                byte[] buffer = new byte[1024];
//                int n = inputStream.read(buffer);
//                //将字节数组转换为字符串
//                if(n==-1){
//                    System.out.printf("[客户端ip：%s,端口号：%d],客户端下线",clientSocket.getInetAddress(),clientSocket.getPort());
//                    break;
//                }
//                String request = new String(buffer,0,n);
                Scanner scanner = new Scanner(inputStream);
                if(!scanner.hasNext()){
                    System.out.printf("[客户端ip：%s,端口号：%d],客户端下线\n",clientSocket.getInetAddress(),clientSocket.getPort());
                    break;
                }
//                1.接受请求并解析
                //客户端必须有一个空格或者换行符
                String request = scanner.next();
//                2.根据请求计算响应
                String respond = process(request);
//                3.返回响应
                //返回的是字节数组类型
//                outputStream.write(request.getBytes(),0,request.getBytes().length);
                //返回字符串类型(各种类型)
                PrintWriter printWriter = new PrintWriter(outputStream);
//                将数据写入数据的缓冲区中
                printWriter.println(respond);
                //冲刷缓冲区
                printWriter.flush();

                //打印日志
                System.out.printf("[客户端ip：%s,端口号：%d],req：%s,resp:%s\n",clientSocket.getInetAddress(),clientSocket.getPort()
                ,request,respond);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                //必须进行close，
                clientSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }
}
